package org.simplesocket.simplenettymtbatis.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.datasource.DataSourceFactory;
import org.simplesocket.simplenettymtbatis.config.DatasourceConfig;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Properties;

@Slf4j
public class DruidDataSourceFactory implements DataSourceFactory {
    
    private Properties props;
    
    @Override
    public void setProperties(Properties props) {
        this.props = props;
    }
    
    @Override
    public DataSource getDataSource() {
        log.info("Preparing to create Druid connection pool ...");
        DruidDataSource ds = new DruidDataSource();
        try {
            // 基本配置
            ds.setDriverClassName(props.getProperty("driver"));
            ds.setUrl(props.getProperty("url"));
            ds.setUsername(props.getProperty("username"));
            ds.setPassword(props.getProperty("password"));
            
            // 连接池配置
            ds.setInitialSize(DatasourceConfig.connectionPoolInitSize); // 初始连接数
            ds.setMinIdle(DatasourceConfig.connectionPoolMinSize); // 最小连接数
            ds.setMaxActive(DatasourceConfig.connectionPoolMaxSize); // 最大连接数
            ds.setMaxWait(DatasourceConfig.connectionPoolMaxWait); // 获取连接等待超时时间
            
            // 检测配置
            ds.setTimeBetweenEvictionRunsMillis(DatasourceConfig.connectionPoolCheckTimeInterval); // 检测间隔
            ds.setMinEvictableIdleTimeMillis(DatasourceConfig.connectionPoolMinFreeTime); // 最小空闲时间
            ds.setMaxEvictableIdleTimeMillis(DatasourceConfig.connectionPoolMaxFreeTime); // 最大空闲时间
            
            // 检测语句
            ds.setKeepAlive(DatasourceConfig.connectionPoolKeepAlive);
            ds.setValidationQuery("SELECT 1");
            ds.setValidationQueryTimeout(5); // 设置验证超时时间
            ds.setTestWhileIdle(true);
            ds.setTestOnBorrow(false);
            ds.setTestOnReturn(false);
            
            // 打开PSCache
            ds.setPoolPreparedStatements(true);
            ds.setMaxPoolPreparedStatementPerConnectionSize(20);
            
            // 配置监控统计拦截的filters
            ds.setFilters("stat,wall");
            
            ds.init();
            log.info("Druid connection pool created ...");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return ds;
    }
}